from io import StringIO

import javalang


class JavaBeanFormat:
    def __init__(self, java_file_path):
        self.tree = self.get_tree(java_file_path)
        self.class_obj = self.get_class()

    def javabean_to_python_json(self, java_file):
        pass

    def get_tree(self, path):
        """
        读取.java文件 使用javalang解析成 CompilationUnit对象
        :param path: .java文件路径
        :return: CompilationUnit对象
        """
        with open(path, 'r', encoding='utf-8') as f:
            return javalang.parse.parse(f.read())

    def get_class(self, node=0):
        # CompilationUnit对象 可能有多个class类 获取第node个class类 的数据
        main_class = self.tree.types[node]
        return main_class

    # def get_class_constructor_parameters(self, class_obj):
    #     # 获取构造器信息
    #     try:
    #         constructor_parameters = class_obj.constructors[0].parameters
    #         constructor_parameters_list = []
    #         for parameter in constructor_parameters:
    #             constructor_parameters_list.append({"type": parameter.type.name, "name": parameter.name})
    #         return constructor_parameters_list
    #     except IndexError:
    #         return []
    #
    # # def get_class_method(self):
    # #     if JavaFileAnalysis.instance_count == 1 and len(self.class_obj.methods) > 1:
    # #         print("注意主类中 有%s个方法" % len(self.class_obj.methods))
    # #     method = self.class_obj.methods[0]
    # #     if "public" not in method.modifiers:
    # #         raise Exception("第一个方法不是public修饰的")
    # #     return method
    #
    # def get_class_method_parameters(self):
    #     parameters_list = []
    #     for parameter in self.class_method.parameters:
    #         parameters_list.append({"type": parameter.type.name, "name": parameter.name})
    #     return parameters_list

    def get_class_fields(self):
        """
        获取当前类的字段
        :param compilation_unit_type: CompilationUnit.types[index]
        :return: list =  [{"type":type.name,"name":name},...]
        """
        field_list = []
        max = len(self.class_obj.fields)
        count = 0
        for field in self.class_obj.fields:
            count = count + 1
            name = field.declarators[0].name
            type = field.type.name
            comments = self._java_comments_to_python_comments(field.documentation)
            field_data = {"name": name, "type": type, "comments": comments}
            if count == max:
                field_data["last"] = True
            field_list.append(field_data)
        return field_list

    def _java_comments_to_python_comments(self, java_comments: str):
        python_comments = ""
        if java_comments.startswith("/**"):
            python_comments = java_comments[3:-2].strip().replace("*", "#")
        elif java_comments.startswith("/*"):
            python_comments = java_comments[2:-2].strip().replace("*", "#")
        elif java_comments.startswith("//"):
            python_comments = java_comments.replace("*", "#")
        return python_comments

    @classmethod
    def fileds_to_str(cls, field_list):
        f = StringIO()
        f.write("{")
        f.write("\n")
        for filed in field_list:
            f.write(f'{filed["comments"]} type : {filed["type"]}')
            f.write("\n")
            f.write(f'"{filed["name"]}": ""')
            if filed.get("last") is None:
                f.write(",")
                f.write("\n")

        f.write("}")
        # print(f.read())
        return f


# get set 开头的所有方法，对应的 声明的字段 类型 与 名称
# def is_getter_setter_class(self):
#     main_class = self.tree.types[0]
#     methods_name = []
#     for method in main_class.methods:
#         methods_name.append(method.name)
#
#     expected_methods_name = []
#     for property_dict in self.class_fields:
#         set_name = "set" + property_dict["name"][0].upper() + property_dict["name"][1:]
#         get_name = "get" + property_dict["name"][0].upper() + property_dict["name"][1:]
#         expected_methods_name.append(set_name)
#         expected_methods_name.append(get_name)
#
#     class_count = len(self.tree.types)
#     if sorted(expected_methods_name) == sorted(methods_name):
#         if class_count == 1 and main_class.modifiers == {"public"}:
#             return True
#     return False
#
# def get_dto_type_name(self):
#     dto_type_name = {"type": self.dto_analysis.class_name,
#                      "name": self.first_char_lower(self.dto_analysis.class_name)}
#     return dto_type_name
#
# def get_class_method_return(self):
#     return_field = {}
#     # 判断返回的是基础数据类型 则返回名称为 方法名称
#     if self.class_method.return_type.name == "boolean":
#         return_field["type"] = self.class_method.return_type.name
#         return_field["name"] = self.class_method.name
#     # 引用类型返回
#     if self.class_method.return_type.name is not None and self.class_method.return_type.name != "boolean":
#         return_field["type"] = self.class_method.return_type.name
#         return_field["name"] = self.first_char_lower(self.class_method.return_type.name)
#     return return_field


if __name__ == "__main__":
    file = r"C:\Users\lc-work\Desktop\PurchaseOrderItemMsgDto.java"

    field_list = JavaBeanFormat(file).get_class_fields()
    f = JavaBeanFormat.fileds_to_str(field_list)
    print(f.getvalue())
